import time
import os
import cv2
from mutagen.mp3 import MP3
from datetime import timedelta


def init(func):
    def wrapper(*args, **kwargs):
        generator = func(*args, **kwargs)
        next(generator)
        return generator

    return wrapper


def time_watcher():
    print('--- %s seconds ---' % (time.time() - start_time))


def find_items(next_coroutine):
    for root, subfolders, files in os.walk(os.getcwd()):
        for file in files:
            next_coroutine.send(os.path.join(root, file))
    next_coroutine.close()


@init
def filter_items(next_coroutine):
    extensions = ['mp4', 'avi']
    # extensions = ['mp3', 'wav']
    try:
        while True:
            filename = yield
            ext = filename.split('.')[-1]
            if ext in extensions:
                next_coroutine.send(filename)
    except GeneratorExit:
        next_coroutine.close()


@init
def get_duration_video(next_coroutine):
    try:
        while True:
            filename = yield
            video = cv2.VideoCapture(filename)
            fps = video.get(cv2.CAP_PROP_FPS)
            frame_count = video.get(cv2.CAP_PROP_FRAME_COUNT)
            duration = frame_count/fps

            data = {'filename': filename, 'duration': int(float(duration))}
            next_coroutine.send(data)
    except GeneratorExit:
        next_coroutine.close()


@init
def print_items(next_coroutine):
    try:
        while True:
            data = yield
            filename = data['filename'].split('\\')[-1]
            duration = data['duration']
            print(filename, str(timedelta(seconds=duration)))
            next_coroutine.send(duration)
    except GeneratorExit:
        next_coroutine.close()


@init
def get_total_duration():
    total = 0
    try:
        while True:
            duration = yield
            total += duration
    except GeneratorExit:
        print('Total duration: ', str(timedelta(seconds=total)))


def pipeline():
    total_duration = get_total_duration()
    printer = print_items(total_duration)
    video_duration = get_duration_video(printer)
    videos = filter_items(video_duration)
    find_items(videos)


if __name__ == '__main__':
    start_time = time.time()
    pipeline()
    time_watcher()
